package com.chao.common.util;

import com.alibaba.fastjson.JSONObject;
import com.chao.common.util.StrUtile;
import com.chao.common.util.exception.SysException;
import com.chao.common.util.reaction.ReactionCode;
import com.chao.common.util.redis.SysRedis;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

import static com.chao.common.util.SysConstant.TOKEN;

/**
 * http工具类
 * chao
 */
public class RequestUtile {

    /**
     * 获取request
     * @return
     */
    public static HttpServletRequest getRequest(){
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes != null) {
            return attributes.getRequest();
        }
        return null;
    }

    /**
     * 获取完整的访问url
     */
    public static String getFullUrl() {
        HttpServletRequest request = getRequest();
        if(null == request){
            return null;
        }
        StringBuffer requstUrl = request.getRequestURL();
        if (request.getQueryString() != null) {
            requstUrl.append('?');
            requstUrl.append(request.getQueryString());
        }
        return requstUrl.toString();
    }

    /**
     * 获取token
     */
    public static String getLoginToken(){
        return getLoginToken(getRequest());
    }

    /**
     * 获取客户标识
     */
    public static String getCustomer(){
        return "business";
    }

    /**
     * 获取token
     */
    public static String getLoginToken(HttpServletRequest request){
        if(null == request){
            return null;
        }
        try {
            String token = request.getHeader(TOKEN);
            if(null == token){
                return request.getParameter(TOKEN);
            }
            return token;
        }catch (Exception e){
            throw new SysException("获取token失败!",e);
        }
    }

    /**
     * 获取当前服务
     */
    public static String getService(){
        HttpServletRequest request = getRequest();
        if(null == request){
            return null;
        }
        try {
            return request.getHeader("service");
        }catch (Exception e){
            throw new SysException("获取当前服务失败!",e);
        }
    }

    /**
     * 查询当前登录用户是否查询所有项目权限  如果只能查询本人项目数据 则返回用户id 否则返回null
     */
    public static String isLoginUserRole(){
        try{
            String token = getLoginToken();
            if(com.chao.common.util.StrUtile.isEmpty(token)){
                return null;
            }
            JSONObject user = SysRedis.getValue(TOKEN+":" + token);
            if(null == user){
                return null;
            }
            if(!"1".equals(user.getString("dataPermission")) && !"1".equals(user.getString("isAdmin"))){
                return user.getString("userId");
            }
        }catch (Exception e){
            return null;
        }
        return null;
    }

    /**
     * 获取当前登录用户id
     */
    public static String getLoginUserId(){
        String token = getLoginToken();
        try {
            JSONObject user = SysRedis.getValue(TOKEN+":" + token);
            return user.getString("userId");
        }catch (Exception e){
            throw new SysException(ReactionCode.LOGIN,"登录异常,请重新登录!",e);
        }
    }

    /**
     * 获取当前登录用户id
     */
    public static <T>T getLoginUser(Class<?> obj){
        return getLoginUser(getLoginToken(),obj);
    }

    /**
     * 获取当前登录用户id
     */
    public static <T>T getLoginUser(String token,Class<?> obj){
        try {
            JSONObject user = SysRedis.getValue(TOKEN+":" + token);
            if(null == user){
                throw new SysException(ReactionCode.LOGIN,"登录异常,请重新登录!");
            }
            if(user.containsKey("name")){
                user.put("userName",user.getString("name"));
            } else if(user.containsKey("userName")){
                user.put("name",user.getString("userName"));
            }
            if(user.containsKey("role")){
                user.put("roleId",user.getString("role"));
            } else if(user.containsKey("roleId")){
                user.put("role",user.getString("roleId"));
            }
            return (T) user.toJavaObject(obj);
        }catch (Exception e){
            throw new SysException(ReactionCode.LOGIN,"登录异常,请重新登录!",e);
        }
    }

    /***
     * 获取客户端ip地址(可以穿透代理)
     */
    public static String getIp() {
        HttpServletRequest request = getRequest();
        if(null == request){
            return null;
        }
        String ip = request.getHeader("X-Forwarded-For");
        if (!com.chao.common.util.StrUtile.isEmpty(ip))
            return ip;

        ip = request.getHeader("x-real-ip");
        if (!com.chao.common.util.StrUtile.isEmpty(ip))
            return ip;

        ip = request.getHeader("Proxy-Client-IP");
        if (!com.chao.common.util.StrUtile.isEmpty(ip))
            return ip;

        ip = request.getHeader("WL-Proxy-Client-IP");
        if (!com.chao.common.util.StrUtile.isEmpty(ip))
            return ip;

        ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        if (!com.chao.common.util.StrUtile.isEmpty(ip))
            return ip;

        ip = request.getHeader("HTTP_X_FORWARDED");
        if (!com.chao.common.util.StrUtile.isEmpty(ip))
            return ip;

        ip = request.getHeader("HTTP_X_CLUSTER_CLIENT_IP");
        if (!com.chao.common.util.StrUtile.isEmpty(ip))
            return ip;

        ip = request.getHeader("HTTP_CLIENT_IP");
        if (!com.chao.common.util.StrUtile.isEmpty(ip))
            return ip;

        ip = request.getHeader("HTTP_FORWARDED_FOR");
        if (!com.chao.common.util.StrUtile.isEmpty(ip))
            return ip;

        ip = request.getHeader("HTTP_FORWARDED");
        if (!com.chao.common.util.StrUtile.isEmpty(ip))
            return ip;

        ip = request.getHeader("HTTP_VIA");
        if (!com.chao.common.util.StrUtile.isEmpty(ip))
            return ip;

        ip = request.getHeader("REMOTE_ADDR");
        if (!com.chao.common.util.StrUtile.isEmpty(ip))
            return ip;

        ip = request.getRemoteAddr();
        return ip;
    }

    /**
     * 校验验证码是否正确
     */
    public static void isVerifyCode(String verifyCode){
        isVerifyCode(verifyCode,"verifyCode");
    }

    /**
     * 校验验证码是否正确
     */
    public static void isVerifyCode(String verifyCode,String key){
        String ip = getIp();
        if (StrUtile.isEmpty(verifyCode)) {
            throw new SysException("请填写验证码!");
        }
        //获取缓存中的验证码
        JSONObject verifyJson = SysRedis.getValue(ip);
        //清除验证码
        SysRedis.delete(ip);
        if (null == verifyJson || !verifyJson.containsKey(key)) {
            throw new SysException("验证码已过期:"+ip);
        }
        if (!verifyJson.getString(key).equals(verifyCode)) {
            throw new SysException("验证码错误!");
        }
    }

}
